package com.nxk.modules.shiro;


import com.nxk.modules.core.entity.BaseEntity;
import com.nxk.modules.core.entity.SysMenuRole;
import com.nxk.modules.core.entity.SysUser;
import com.nxk.modules.core.entity.vo.MenuRoleVo;
import com.nxk.modules.core.service.SysMenuRoleService;
import com.nxk.modules.core.service.SysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
 * 自定义realm
 */
public class MyRealm extends AuthorizingRealm {

    @Autowired
    private SysMenuRoleService sysMenuRoleService;

    @Autowired
    private SysUserService sysUserService;


    /**
     * 执行授权逻辑
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        SysUser sysUser = (SysUser) principalCollection.getPrimaryPrincipal();
        //查询该用户的所有菜单权限
        List<MenuRoleVo> menuRoleVos = sysMenuRoleService.queryMenuByRoleCode(sysUser.getUserRole());
        Set<String> roleSet = new HashSet<>();
        Set<String> permissionSet = new HashSet<>();
        menuRoleVos.stream().forEach(menuRoleVo -> {
            if (MenuRoleVo.ROLE.equals(menuRoleVo.getMenuRole())){
                permissionSet.add(menuRoleVo.getMenuIdent());
            }
        });
        roleSet.add(sysUser.getUserRole());
        info.setRoles(roleSet); //设置角色
        info.setStringPermissions(permissionSet);  //设置权限
        return info;
    }

    /**
     * 执行认证逻辑,
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String loginCode = (String) authenticationToken.getPrincipal();
        SysUser sysUser = sysUserService.getUserByLoginCode(loginCode);
        if (sysUser == null) {
            throw new UnknownAccountException("账户" + loginCode + "不存在！");
        }
        if (BaseEntity.STATUS_STOP.equals(sysUser.getStatus())){
            throw new UnknownAccountException("账户已停用,请联系管理");
        }
        return new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), ByteSource.Util.bytes(sysUser.getSalt()), getName());
    }


}
